home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Freeware / Griffith 0.9.8 / griffith-0.9.8-win32.exe / {app} / lib / plugins / movie / PluginMovieIMDB-de.py < prev    next >
Text File  |  2008-11-17  |  15KB  |  398 lines

  1. # -*- coding: UTF-8 -*-
  2.  
  3. __revision__ = '$Id: PluginMovieIMDB-de.py 1042 2008-11-15 21:59:58Z mikej06 $'
  4.  
  5. # Copyright (c) 2007 Michael Jahn
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. # GNU Library General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software
  19. # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  20.  
  21. # You may use and distribute this software under the terms of the
  22. # GNU General Public License, version 2 or later
  23.  
  24. import gutils, movie
  25. import string, re
  26.  
  27. plugin_name         = 'IMDb-de'
  28. plugin_description  = 'Internet Movie Database German'
  29. plugin_url          = 'german.imdb.com'
  30. plugin_language     = _('German')
  31. plugin_author       = 'Michael Jahn'
  32. plugin_author_email = 'mikej06@hotmail.com'
  33. plugin_version      = '1.3'
  34.  
  35. class Plugin(movie.Movie):
  36.     def __init__(self, id):
  37.         self.encode = 'iso8859-1'
  38.         self.movie_id = id
  39.         self.url = "http://german.imdb.com/title/tt%s" % str(self.movie_id)
  40.  
  41.     def initialize(self):
  42.         self.cast_page = self.open_page(url=self.url + '/fullcredits')
  43.         self.plot_page = self.open_page(url=self.url + '/plotsummary')
  44.         # correction of all &#xxx entities
  45.         self.page = self.page.decode(self.encode)
  46.         self.page = gutils.convert_entities(self.page)
  47.         self.page = self.page.encode(self.encode)
  48.         self.cast_page = self.cast_page.decode(self.encode)
  49.         self.cast_page = gutils.convert_entities(self.cast_page)
  50.         self.cast_page = self.cast_page.encode(self.encode)
  51.         self.plot_page = self.plot_page.decode(self.encode)
  52.         self.plot_page = gutils.convert_entities(self.plot_page)
  53.         self.plot_page = self.plot_page.encode(self.encode)
  54.  
  55.     def get_image(self):
  56.         tmp = string.find(self.page, 'a name="poster"')
  57.         if tmp == -1:        # poster not available
  58.             self.image_url = ''
  59.         else:
  60.             self.image_url = gutils.trim(self.page[tmp:], 'src="', '"')
  61.  
  62.     def get_o_title(self):
  63.         self.o_title = gutils.trim(self.page, '<h1>', '<span')
  64.  
  65.     def get_title(self):
  66.         self.title = gutils.trim(self.page, '<h1>', '<span')
  67.         elements = string.split(self.regextrim(self.page, '<h5>(Alternativ|Auch bekannt als):', '</div>'), '<i class="transl"')
  68.         if len(elements) > 1:
  69.             for element in elements:
  70.                 tmp = gutils.before(gutils.trim(element, '>', '[de]'), '(')
  71.                 if tmp <> '':
  72.                     self.title = tmp
  73.                     break
  74.  
  75.     def get_director(self):
  76.         self.director = gutils.trim(self.page,'<h5>Regie</h5>', '<br/>')
  77.         if self.director == '':
  78.             self.director = gutils.trim(self.page,'<h5>Regisseur:</h5>', '</div>')
  79.         self.director = self.__before_more(self.director)
  80.         self.director = self.director.replace('<br/>', ', ')
  81.         self.director = gutils.clean(self.director)
  82.         self.director = re.sub(',$', '', self.director)
  83.  
  84.     def get_plot(self):
  85.         self.plot = gutils.trim(self.page, '<h5>Kurzbeschreibung:</h5>', '</div>')
  86.         self.plot = self.__before_more(self.plot)
  87.         elements = string.split(self.plot_page, '<p class="plotpar">')
  88.         if len(elements) > 1:
  89.             self.plot = self.plot + '\n\n'
  90.             elements[0] = ''
  91.             for element in elements:
  92.                 if element != '':
  93.                     self.plot = self.plot + gutils.strip_tags(gutils.before(element, '</a>')) + '\n'
  94.  
  95.     def get_year(self):
  96.         self.year = gutils.trim(self.page, '<a href="/Sections/Years/', '</a>')
  97.         self.year = gutils.after(self.year, '">')
  98.  
  99.     def get_runtime(self):
  100.         self.runtime = self.regextrim(self.page, '<h5>L[^n]+nge:</h5>', ' [Mm]in')
  101.  
  102.     def get_genre(self):
  103.         self.genre = gutils.trim(self.page, '<h5>Genre:</h5>', '</div>')
  104.         self.genre = self.__before_more(self.genre)
  105.  
  106.     def get_cast(self):
  107.         self.cast = ''
  108.         self.cast = gutils.trim(self.cast_page, '<table class="cast">', '</table>')
  109.         if self.cast == '':
  110.             self.cast = gutils.trim(self.page, '<table class="cast">', '</table>')
  111.         self.cast = string.replace(self.cast, ' ... ', _(' as ').encode('utf8'))
  112.         self.cast = string.replace(self.cast, '...', _(' as ').encode('utf8'))
  113.         self.cast = string.replace(self.cast, '</tr><tr>', "\n")
  114.         self.cast = string.replace(self.cast, '</tr><tr class="even">', "\n")
  115.         self.cast = string.replace(self.cast, '</tr><tr class="odd">', "\n")
  116.         self.cast = self.__before_more(self.cast)
  117.         self.cast = re.sub('[ ]+', ' ', self.cast)
  118.  
  119.     def get_classification(self):
  120.         self.classification = gutils.trim(gutils.trim(self.page, 'Altersfreigabe:', '</div>'), 'Germany:', '&')
  121.  
  122.     def get_studio(self):
  123.         self.studio = gutils.trim(self.page, '<h5>Firma:</h5>', '</div>')
  124.         self.studio = self.__before_more(self.studio)
  125.  
  126.     def get_o_site(self):
  127.         self.o_site = ''
  128.  
  129.     def get_site(self):
  130.         self.site = "http://german.imdb.com/title/tt%s" % self.movie_id
  131.  
  132.     def get_trailer(self):
  133.         self.trailer = "http://german.imdb.com/title/tt%s/trailers" % self.movie_id
  134.  
  135.     def get_country(self):
  136.         self.country = gutils.trim(self.page, '<h5>Land:</h5>', '</div>')
  137.         self.country = self.__before_more(self.country)
  138.         self.country = re.sub('[\n]+', '', self.country)
  139.         self.country = re.sub('[ ]+', ' ', self.country)
  140.  
  141.     def get_rating(self):
  142.         self.rating = gutils.trim(self.page, '<h5>Nutzer-Bewertung:</h5>', '/10')
  143.         if self.rating:
  144.             try:
  145.                 self.rating = str(float(gutils.clean(self.rating)))
  146.             except:
  147.                 self.rating = ''
  148.  
  149.     def get_notes(self):
  150.         self.notes = ''
  151.         language = gutils.trim(self.page, '<h5>Sprache:</h5>', '</div>')
  152.         language = gutils.strip_tags(language)
  153.         language = re.sub('[\n]+', '', language)
  154.         language = re.sub('[ ]+', ' ', language)
  155.         language = language.rstrip()
  156.         color = gutils.trim(self.page, '<h5>Farbe:</h5>', '</div>')
  157.         color = gutils.strip_tags(color)
  158.         color = re.sub('[\n]+', '', color)
  159.         color = re.sub('[ ]+', ' ', color)
  160.         color = re.sub('[ ]+$', '', color)
  161.         color = color.rstrip()
  162.         sound = gutils.trim(self.page, '<h5>Tonverfahren:</h5>', '</div>')
  163.         sound = gutils.strip_tags(sound)
  164.         sound = re.sub('[\n]+', '', sound)
  165.         sound = re.sub('[ ]+', ' ', sound)
  166.         sound = sound.rstrip()
  167.         soundsplit = sound.split(' | ')
  168.         if len(soundsplit) > 1:
  169.             soundsplit.sort()
  170.             sound = ''
  171.             for elem in soundsplit:
  172.                 sound += elem + ' | '
  173.             sound = sound[0:len(sound) - 3]
  174.         tagline = gutils.trim(self.page, '<h5>Werbezeile:</h5>', '</div>')
  175.         tagline = self.__before_more(tagline)
  176.         tagline = gutils.strip_tags(tagline)
  177.         tagline = re.sub('[\n]+', '', tagline)
  178.         tagline = re.sub('[ ]+', ' ', tagline)
  179.         tagline = tagline.rstrip()
  180.         if len(language)>0:
  181.             self.notes = "%s: %s\n" %(_('Language').encode('utf8'), language)
  182.         if len(sound)>0:
  183.             self.notes += "%s: %s\n" %(gutils.strip_tags(_('<b>Audio</b>').encode('utf8')), sound)
  184.         if len(color)>0:
  185.             self.notes += "%s: %s\n" %(_('Color').encode('utf8'), color)
  186.         if len(tagline)>0:
  187.             self.notes += "%s: %s\n" %('Tagline', tagline)
  188.     
  189.     def __before_more(self, data):
  190.         tmp = string.find(data, '>mehr<')
  191.         if tmp>0:
  192.             data = data[:tmp] + '>'
  193.         return data
  194.  
  195.     def regextrim(self,text,key1,key2):
  196.         obj = re.search(key1, text)
  197.         if obj is None:
  198.             return ''
  199.         else:
  200.             p1 = obj.end()
  201.         obj = re.search(key2, text[p1:])
  202.         if obj is None:
  203.             return ''
  204.         else:
  205.             p2 = p1 + obj.start()
  206.         return text[p1:p2]
  207.  
  208. class SearchPlugin(movie.SearchMovie):
  209.     PATTERN = re.compile(r"""<a href=['"]/title/tt([0-9]+)/["']>(.*?)(</td>|</A>)""", re.IGNORECASE)
  210.     PATTERN_POWERSEARCH = re.compile(r"""Here are the [0-9]+ matching titles""")
  211.  
  212.     def __init__(self):
  213.         self.original_url_search    = 'http://german.imdb.com/find?more=tt&q='
  214.         self.translated_url_search    = 'http://german.imdb.com/find?more=tt&q='
  215.         self.encode = 'iso8859-1'
  216.         self.remove_accents = False
  217.  
  218.     def search(self,parent_window):
  219.         self.open_search(parent_window)
  220.         tmp = gutils.trim(self.page, ' angezeigt)', ' Treffergenauigkeit')
  221.         if tmp == '':
  222.             if self.PATTERN_POWERSEARCH.search(self.page) is None:
  223.                 self.page = ''
  224.         else:
  225.             self.page = tmp 
  226.         # correction of all &#xxx entities
  227.         self.page = self.page.decode(self.encode)
  228.         self.page = gutils.convert_entities(self.page)
  229.         self.page = self.page.encode(self.encode)
  230.         return self.page
  231.  
  232.     def get_searches(self):
  233.         elements = string.split(self.page, '<tr>')
  234.         if len(elements) < 2:
  235.             elements = string.split(self.page, '<TR>')
  236.  
  237.         if len(elements):
  238.             for element in elements[1:]:
  239.                 match = self.PATTERN.findall(element)
  240.                 for entry in match:
  241.                     tmp  = gutils.clean(entry[1])
  242.                     self.ids.append(entry[0])
  243.                     self.titles.append(tmp)
  244.  
  245. #
  246. # Plugin Test
  247. #
  248. class SearchPluginTest(SearchPlugin):
  249.     #
  250.     # Configuration for automated tests:
  251.     # dict { movie_id -> [ expected result count for original url, expected result count for translated url ] }
  252.     #
  253.     test_configuration = {
  254.         'Rocky Balboa'            : [ 3, 13 ],
  255.         'Ein gl├╝ckliches Jahr'    : [ 1, 30 ]
  256.     }
  257.  
  258. class PluginTest:
  259.     #
  260.     # Configuration for automated tests:
  261.     # dict { movie_id -> dict { arribute -> value } }
  262.     #
  263.     # value: * True/False if attribute only should be tested for any value
  264.     #        * or the expected value
  265.     #
  266.     test_configuration = {
  267.         '0479143' : { 
  268.             'title'             : 'Rocky Balboa',
  269.             'o_title'             : 'Rocky Balboa',
  270.             'director'            : 'Sylvester Stallone',
  271.             'plot'                 : True,
  272.             'cast'                : 'Sylvester Stallone' + _(' as ') + 'Rocky Balboa\n\
  273. Burt Young' + _(' as ') + 'Paulie Panina\n\
  274. Antonio Tarver' + _(' as ') + 'Mason \'The Line\' Dixon\n\
  275. Geraldine Hughes' + _(' as ') + 'Marie\n\
  276. Milo Ventimiglia' + _(' as ') + 'Robert Balboa Jr.\n\
  277. Tony Burton' + _(' as ') + 'Duke\n\
  278. A.J. Benza' + _(' as ') + 'L.C.\n\
  279. James Francis Kelly III' + _(' as ') + 'Steps\n\
  280. Talia Shire' + _(' as ') + 'Adrian (archive footage)\n\
  281. Lou DiBella' + _(' as ') + 'Himself\n\
  282. Mike Tyson' + _(' as ') + 'Himself\n\
  283. Henry G. Sanders' + _(' as ') + 'Martin\n\
  284. Pedro Lovell' + _(' as ') + 'Spider Rico\n\
  285. Ana Gerena' + _(' as ') + 'Isabel\n\
  286. Angela Boyd' + _(' as ') + 'Angie\n\
  287. Louis Giansante' + _(' as ') + 'Bar Thug\n\
  288. Maureen Schilling' + _(' as ') + 'Lucky\'s Bartender\n\
  289. Lahmard J. Tate' + _(' as ') + 'X-Cell (as Lahmard Tate)\n\
  290. Woody Paige' + _(' as ') + 'ESPN Commentator (as Woodrow W. Paige)\n\
  291. Skip Bayless' + _(' as ') + 'ESPN Commentator\n\
  292. Jay Crawford' + _(' as ') + 'ESPN Commentator\n\
  293. Brian Kenny' + _(' as ') + 'ESPN Host\n\
  294. Dana Jacobson' + _(' as ') + 'ESPN Host\n\
  295. Charles Johnson' + _(' as ') + 'ESPN Host (as Chuck Johnson)\n\
  296. James Binns' + _(' as ') + 'Commissioner (as James J. Binns)\n\
  297. Johnnie Hobbs Jr.' + _(' as ') + 'Commissioner\n\
  298. Barney Fitzpatrick' + _(' as ') + 'Commissioner\n\
  299. Jim Lampley' + _(' as ') + 'HBO Commentator\n\
  300. Larry Merchant' + _(' as ') + 'HBO Commentator\n\
  301. Max Kellerman' + _(' as ') + 'HBO Commentator\n\
  302. LeRoy Neiman' + _(' as ') + 'Himself\n\
  303. Bert Randolph Sugar' + _(' as ') + 'Ring Magazine Reporter\n\
  304. Bernard Fern├índez' + _(' as ') + 'Boxing Association of America Writer (as Bernard Fernandez)\n\
  305. Gunnar Peterson' + _(' as ') + 'Weightlifting Trainer\n\
  306. Yahya' + _(' as ') + 'Dixon\'s Opponent\n\
  307. Marc Ratner' + _(' as ') + 'Weigh-In Official\n\
  308. Anthony Lato Jr.' + _(' as ') + 'Rocky\'s Inspector\n\
  309. Jack Lazzarado' + _(' as ') + 'Dixon\'s Inspector\n\
  310. Michael Buffer' + _(' as ') + 'Ring Announcer\n\
  311. Joe Cortez' + _(' as ') + 'Referee\n\
  312. Carter Mitchell' + _(' as ') + 'Shamrock Foreman\n\
  313. Vinod Kumar' + _(' as ') + 'Ravi\n\
  314. Fran Pultro' + _(' as ') + 'Father at Restaurant\n\
  315. Frank Stallone' + _(' as ') + 'Dinner Patron (as Frank Stallone Jr.)\n\
  316. Jody Giambelluca' + _(' as ') + 'Dinner Patron\n\
  317. Tobias Segal' + _(' as ') + 'Robert\'s Friend\n\
  318. Tim Carr' + _(' as ') + 'Robert\'s Friend\n\
  319. Matt Frack' + _(' as ') + 'Robert\'s Friend #3\n\
  320. Paul Dion Monte' + _(' as ') + 'Robert\'s Friend\n\
  321. Kevin King Templeton' + _(' as ') + 'Robert\'s Friend (as Kevin King-Templeton)\n\
  322. Robert Michael Kelly' + _(' as ') + 'Mr. Tomilson\n\
  323. Rick Buchborn' + _(' as ') + 'Rocky Fan\n\
  324. Nick Baker' + _(' as ') + 'Irish Pub Bartender\n\
  325. Don Sherman' + _(' as ') + 'Andy\n\
  326. Stu Nahan' + _(' as ') + 'Computer Fight Commentator (voice)\n\
  327. Gary Compton' + _(' as ') + 'Security Guard\n\
  328. ├╝brige Besetzung in alphabetischer Reihenfolge:\n\
  329. Ricky Cavazos' + _(' as ') + 'Boxing Spectator (uncredited)\n\
  330. David Kneeream' + _(' as ') + 'Adrian\'s Patron (uncredited)\n\
  331. Dolph Lundgren' + _(' as ') + 'Captain Ivan Drago (archive footage) (uncredited)\n\
  332. Burgess Meredith' + _(' as ') + 'Mickey Goldmill (archive footage) (uncredited)\n\
  333. Keith Moyer' + _(' as ') + 'Bar Patron (uncredited)\n\
  334. Mr. T' + _(' as ') + 'Clubber Lang (archive footage) (uncredited)',
  335.             'country'            : 'USA',
  336.             'genre'                : 'Action | Sport',
  337.             'classification'    : False,
  338.             'studio'            : 'Metro-Goldwyn-Mayer (MGM)',
  339.             'o_site'            : False,
  340.             'site'                : 'http://german.imdb.com/title/tt0479143',
  341.             'trailer'            : 'http://german.imdb.com/title/tt0479143/trailers',
  342.             'year'                : 2006,
  343.             'notes'                : _('Language') + ': Englisch | Spanisch\n'\
  344. + _('Audio') + ': DTS | Dolby Digital | SDDS\n'\
  345. + _('Color') + ': Farbe\n\
  346. Tagline: It ain\'t over \'til it\'s over.',
  347.             'runtime'            : 102,
  348.             'image'                : True,
  349.             'rating'            : 7
  350.         },
  351.         '0069815' : { 
  352.             'title'             : 'Gl├╝ckliches Jahr, Ein',
  353.             'o_title'             : 'Bonne ann├⌐e, La',
  354.             'director'            : 'Claude Lelouch',
  355.             'plot'                 : True,
  356.             'cast'                : 'Lino Ventura' + _(' as ') + 'Simon\n\
  357. Fran├ºoise Fabian' + _(' as ') + 'Fran├ºoise\n\
  358. Charles G├⌐rard' + _(' as ') + 'Charlot\n\
  359. Andr├⌐ Falcon' + _(' as ') + 'Le bijoutier\n\
  360. Mireille Mathieu' + _(' as ') + 'Herself / Elle-m├¬me\n\
  361. Lilo' + _(' as ') + 'Madame F├⌐lix\n\
  362. Claude Mann' + _(' as ') + 'L\'intellectuel\n\
  363. Fr├⌐d├⌐ric de Pasquale' + _(' as ') + 'L\'amant parisien\n\
  364. G├⌐rard Sire' + _(' as ') + 'Le directeur de la prison\n\
  365. Silvano Tranquilli' + _(' as ') + 'L\'amant italien\n\
  366. Andr├⌐ Barello\n\
  367. Michel Bertay\n\
  368. Norman de la Chesnaye\n\
  369. Pierre Edeline\n\
  370. Pierre Pontiche\n\
  371. Michou' + _(' as ') + 'Himself\n\
  372. Bettina Rheims' + _(' as ') + 'La jeune vendeuse\n\
  373. Joseph Rythmann\n\
  374. Georges Staquet\n\
  375. Jacques Villedieu\n\
  376. Harry Walter\n\
  377. ├╝brige Besetzung in alphabetischer Reihenfolge:\n\
  378. Anouk Aim├⌐e' + _(' as ') + 'Une femme (archive footage) (uncredited)\n\
  379. Elie Chouraqui' + _(' as ') + '(uncredited)\n\
  380. R├⌐my Julienne' + _(' as ') + 'Chauffeur de taxi (uncredited)\n\
  381. Jean-Louis Trintignant' + _(' as ') + 'Un homme (archive footage) (uncredited)',
  382.             'country'            : 'France | Italy',
  383.             'genre'                : 'Kom├╢die',
  384.             'classification'    : False,
  385.             'studio'            : 'Les Films 13',
  386.             'o_site'            : False,
  387.             'site'                : 'http://german.imdb.com/title/tt0069815',
  388.             'trailer'            : 'http://german.imdb.com/title/tt0069815/trailers',
  389.             'year'                : 1973,
  390.             'notes'                : _('Language') + ': Franz├╢sisch\n'\
  391. + _('Audio') + ': Mono\n'\
  392. + _('Color') + ': Farbe (Eastmancolor)',
  393.             'runtime'            : 90,
  394.             'image'                : True,
  395.             'rating'            : 7
  396.         },
  397.     }
  398.